package cn.monkey.family.server.data.mongo;

import cn.monkey.family.data.Entity;
import cn.monkey.family.data.context.UserSessionContextHolder;
import cn.monkey.family.data.uc.auth.UserSession;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import java.util.function.Consumer;

@Configuration
@EnableMongoRepositories(
        basePackages = "cn.monkey.family.server.domain"
)
public class MongoConfiguration {

    static class BeforeSaveEventListener implements ApplicationListener<BeforeSaveEvent<? extends Entity>> {

        private final UserSessionContextHolder userSessionContextHolder;

        BeforeSaveEventListener(UserSessionContextHolder userSessionContextHolder) {
            this.userSessionContextHolder = userSessionContextHolder;
        }

        static <T> void trySet(T t, Consumer<T> consumer, T value) {
            if (t == null) {
                consumer.accept(value);
            }
        }

        @Override
        public void onApplicationEvent(BeforeSaveEvent<? extends Entity> event) {
            Entity entity = event.getSource();
            // 这里的userSessionContextHolder
            UserSession userSession = this.userSessionContextHolder.get();
            long currentTime = System.currentTimeMillis();
            trySet(entity.getCreatedTime(), entity::setCreatedTime, currentTime);
            trySet(entity.getUpdatedTime(), entity::setUpdatedTime, currentTime);
            if (userSession != null) {
                trySet(entity.getCreatorId(), entity::setCreatorId, userSession.getUid());
                trySet(entity.getUpdaterId(), entity::setUpdaterId, userSession.getUid());
            }
            trySet(entity.getEnabled(), entity::setEnabled, true);
        }
    }

    @Bean
    BeforeSaveEventListener beforeSaveEventListener(UserSessionContextHolder userSessionContextHolder) {
        return new BeforeSaveEventListener(userSessionContextHolder);
    }
}
